
/*
1. 解引用裸指针，就如上例所示
2. 调用一个 unsafe 或外部的函数
3. 访问或修改一个可变的静态变量
4. 实现一个 unsafe 特征
5. 访问 union 中的字段
*/

/* // 1.
fn main() {
    // println!("Hello, world!");

    let num: i8 = 5;

    let r1 = &num as *const i8;

    unsafe {
        println!("r1 is {}", *r1);
    }
}
*/

/*
// *const T 不可变raw pointer, *mut T 可变raw pointer
// 创建裸指针是安全的行为，而解引用裸指针才是不安全的行为
// create raw pointer from ref
fn main() {
    let mut n = 5;

    let r1 = &n as *const i32;
    let r2 = &mut n as *mut i32;    

    unsafe {
        println!("r1 is {}", *r1);
        *r2 += 3;
        println!("r2 is {}", *r2);
    }
}
*/

/* 
// create raw pointer from address 
use std::{slice::from_raw_parts,str::from_utf8_unchecked};

// 获取字符串的内存地址和长度
fn get_memory_location() -> (usize, usize) {
    let s = "Hello rust!";
    let ptr = s.as_ptr() as usize;
    let l = s.len();
    (ptr, l)
}

// 
fn get_str_at_location(ptr: usize, l: usize) -> &'static str {
    unsafe {
        from_utf8_unchecked(from_raw_parts(ptr as *const u8, l))
    }
}

fn main() {
    // NOTICE: just use random address is dangerous action. as below code.
    // let address: usize = 0x012345;
    // let r1 = address as *const i32;
    
    // so always get the address first, then use it
    let (ptr, l) = get_memory_location();
    let msg = get_str_at_location(ptr, l);    
    //unsafe {
        println!("The {} bytes at location 0x{} stores: {}", l, ptr, msg);
    //}

    //let tptr: usize = 140695482643768;
    //let tl: usize = 11;    
    //let msg = get_str_at_location(tptr, tl);    
    //println!("The {} bytes at location 0x{} stores: {}", tl, tptr, msg);
}
*/

/*
// create raw pointer from ref
fn main() {
    let a = 1;
    let b: *const i32 = &a as *const i32;
    let c: *const i32 = &a;

    unsafe {
        println!("b is {}", *b);
        println!("c is {}", *c);
    }
}
*/

// create raw pointer from Box pointer.
fn main() {
    let a: Box<i32> = Box::new(10);
    let b: *const i32 = &*a;
    let c: *const i32 = Box::into_raw(a);

    unsafe {
        println!("b is {}", *b);
        println!("c is {}", *c);
    }
}
